home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / tools / czesc_2 / ispell-3.3ljr / ispell / good.c < prev    next >
C/C++ Source or Header  |  1992-09-22  |  15KB  |  844 lines

  1. /*
  2.  * good.c - see if a word or its root word
  3.  * is in the dictionary.
  4.  *
  5.  * Pace Willisson, 1983
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include <string.h>
  11. #include "config.h"
  12. #include "ispell.h"
  13.  
  14. static int wordok;
  15. static char *orig_word;
  16.  
  17. extern int cflag;
  18.  
  19. int 
  20. good (char *w)
  21. {
  22.   char nword[100];
  23.   register char *p, *q;
  24.   register n;
  25.  
  26.   /*
  27.   ** Make an uppercase copy of the word we are checking.
  28.   */
  29.   for (p = w, q = nword; *p; p++, q++)
  30.     {
  31.       if (mylower (*p))
  32.     *q = toupper (*p);
  33.       else
  34.     *q = *p;
  35.     }
  36.   *q = 0;
  37.  
  38.   rootword[0] = 0;
  39.  
  40.   if (cflag)
  41.     {
  42.       printf ("%s\n", w);
  43.       orig_word = w;
  44.     }
  45.   else if (lookup (nword, q - nword, 1) != NULL)
  46.     {
  47. #ifdef CAPITALIZE
  48.       return cap_ok (w, lastdent);
  49. #else
  50.       return (1);
  51. #endif
  52.     }
  53.  
  54.   /* try stripping off suffixes */
  55.  
  56.   n = strlen (w);
  57.   if (n == 1)
  58.     return (1);
  59.  
  60.   if (n < 4)
  61.     return 0;
  62.  
  63.   wordok = 0;
  64.  
  65.   /* this part from 'check.mid' */
  66.   switch (q[-1])
  67.     {
  68.     case 'D':
  69.       d_ending (nword, n);
  70.       break;            /* FOR "CREATED", "IMPLIED", "CROSSED" */
  71.     case 'T':
  72.       t_ending (nword, n);
  73.       break;            /* FOR "LATEST", "DIRTIEST", "BOLDEST" */
  74.     case 'R':
  75.       r_ending (nword, n);
  76.       break;            /* FOR "LATER", "DIRTIER", "BOLDER" */
  77.     case 'G':
  78.       g_ending (nword, n);
  79.       break;            /* FOR "CREATING", "FIXING" */
  80.     case 'H':
  81.       h_ending (nword, n);
  82.       break;            /* FOR "HUNDREDTH", "TWENTIETH" */
  83.     case 'S':
  84.       s_ending (nword, n);
  85.       break;            /* FOR ALL SORTS OF THINGS ENDING IN "S" */
  86.     case 'N':
  87.       n_ending (nword, n);
  88.       break;            /* "TIGHTEN", "CREATION", "MULIPLICATION" */
  89.     case 'E':
  90.       e_ending (nword, n);
  91.       break;            /* FOR "CREATIVE", "PREVENTIVE" */
  92.     case 'Y':
  93.       y_ending (nword, n);
  94.       break;            /* FOR "QUICKLY" */
  95.     default:
  96.       break;
  97.     }
  98.  
  99.   if (wordok)
  100.     {
  101.       strcpy (rootword, lastdent->word);
  102. #ifdef CAPITALIZE
  103.       return cap_ok (w, lastdent);
  104. #else
  105.       return 1;
  106. #endif
  107.     }
  108.   return 0;
  109. }
  110.  
  111. #ifdef CAPITALIZE
  112. int 
  113. cap_ok (char *word, struct dent * dent)
  114. {
  115.   register char *dword;
  116.   register char *w;
  117.   int wcount;
  118.  
  119.   /*
  120.   ** All caps is always legal.
  121.   */
  122.   for (dword = word; *dword; dword++)
  123.     {
  124.       if (mylower (*dword))
  125.     break;
  126.     }
  127.   if (*dword == '\0')
  128.     return 1;            /* It was all caps */
  129.   if (dent->allcaps)
  130.     return 0;            /* Not all caps and required to be */
  131.   if (dent->followcase)
  132.     {
  133.       /*
  134.       ** It's a followcase word.  The correct capitalizations are
  135.       ** found following the main dent word.  When we find a
  136.       ** mismatch between letters, we assume we are in the suffix,
  137.       ** and begin insisting on the same case as the last letter
  138.       ** that matched.
  139.       */
  140.       dword = dent->word + strlen (dent->word) + 1;
  141.       wcount = *dword++ & 0xFF;
  142.       while (--wcount >= 0)
  143.     {
  144.       dword++;        /* Skip over keep flag */
  145.       for (w = word; *w; w++, dword++)
  146.         {
  147.           if (*dword != *w)
  148.         {
  149.           /* Begin suffix processing.  */
  150.           if (myupper (dword[-1]))
  151.             {
  152.               while (*w && !mylower (*w))
  153.             w++;
  154.               if (*w == '\0')
  155.             return 1;
  156.             }
  157.           else
  158.             {
  159.               while (*w && !myupper (*w))
  160.             w++;
  161.               if (*w == '\0')
  162.             return 1;
  163.             }
  164.           break;
  165.         }
  166.         }
  167.       if (*w == '\0')
  168.         return 1;
  169.       while (*dword++)    /* Skip to next prototype */
  170.         ;
  171.     }
  172.     }
  173.   /*
  174.   ** If it's a capitalize word, and the first letter is lowercase,
  175.   ** it's illegal.  Note that all-lowercase followcase words will
  176.   ** be found by the string scan above.
  177.   */
  178.   if (dent->capitalize && mylower (*word))
  179.     return 0;
  180.   /*
  181.   ** If it's not a followcase word, or if the capitalize flag is set,
  182.   ** capitalization (e.g. at the beginning of a sentence) is always
  183.   ** legal.  All-lowercase is also legal for non-followcase words.
  184.   */
  185.   if (!dent->followcase || dent->capitalize)
  186.     {
  187.       for (dword = word + 1; *dword; dword++)
  188.     {
  189.       if (myupper (*dword))
  190.         break;
  191.     }
  192.       if (*dword == '\0')
  193.     return 1;        /* It was all-lower or capitalized */
  194.     }
  195.   return 0;            /* Word has a bad mix of cases */
  196. }
  197.  
  198. #endif
  199.  
  200. void 
  201. flagpr (char *w, int flag, char *modpoint)
  202. {
  203.   register char *orig;
  204.  
  205.   /*
  206.   ** We refuse to print if the case at and after modpoint isn't
  207.   ** consistent with the case just before there.  This prevents
  208.   ** things like "OEM's" from being turned into OEM/M, which in
  209.   ** turn will only accept "OEM'S".
  210.   */
  211.   orig = orig_word + (modpoint - w);
  212.   if (myupper (orig[-1]))
  213.     {
  214.       while (*orig)
  215.     {
  216.       if (mylower (*orig++))
  217.         return;
  218.     }
  219.     }
  220.   else
  221.     {
  222.       while (*orig)
  223.     {
  224.       if (myupper (*orig++))
  225.         return;
  226.     }
  227.     }
  228.   /* Case is ok.  Now print it. */
  229.   for (orig = orig_word; *w && w < modpoint; orig++, w++)
  230.     putchar (*orig);
  231.   if (myupper (orig[-1]))
  232.     printf ("%s", w);
  233.   else
  234.     {
  235.       for (; *w; w++)
  236.     {
  237.       if (myupper (*w))
  238.         putchar (tolower (*w));
  239.       else
  240.         putchar (*w);
  241.     }
  242.     }
  243.   printf ("/%c\n", flag);
  244. }
  245.  
  246. void 
  247. g_ending (char *w, int n)
  248. {
  249.   register char *p;
  250.   register struct dent *dent;
  251.  
  252.   p = w + n - 3;        /* if the word ends in 'ing', then *p == 'i' */
  253.  
  254.   if (strcmp (p, "ING") != 0)
  255.     return;
  256.  
  257.   *p = 'E';            /* change I to E, like in CREATING */
  258.   *(p + 1) = 0;
  259.   n -= 2;
  260.  
  261.   if (n < 2)
  262.     return;
  263.  
  264.   if (cflag)
  265.     flagpr (w, 'G', p);
  266.   else if ((dent = lookup (w, n, 1)) != NULL
  267.        && dent->g_flag)
  268.     {
  269.       wordok = 1;
  270.       return;
  271.     }
  272.  
  273.  
  274.   *p = 0;
  275.   n--;
  276.  
  277.   if (n < 2)
  278.     return;
  279.  
  280.   if (p[-1] == 'E')
  281.     return;            /* this stops CREATEING */
  282.  
  283.   if (cflag)
  284.     flagpr (w, 'G', p);
  285.   else if ((dent = lookup (w, n, 1)) != NULL)
  286.     {
  287.       if (dent->g_flag)
  288.     wordok = 1;
  289.       return;
  290.     }
  291.   return;
  292. }
  293.  
  294. void 
  295. d_ending (char *w, int n)
  296. {
  297.   register char *p;
  298.   register struct dent *dent;
  299.  
  300.   p = w + n - 2;
  301.  
  302.   if (strcmp (p, "ED") != 0)
  303.     return;
  304.  
  305.   p[1] = 0;            /* kill 'D' */
  306.   n--;
  307.  
  308.   if (cflag)
  309.     flagpr (w, 'D', p + 1);
  310.   else if ((dent = lookup (w, n, 1)) != NULL)
  311.     {                /* eg CREATED */
  312.       if (dent->d_flag)
  313.     {
  314.       wordok = 1;
  315.       return;
  316.     }
  317.     }
  318.  
  319.   if (n < 3)
  320.     return;
  321.  
  322.   p[0] = 0;
  323.   n--;
  324.   p--;
  325.  
  326.   /* ED is now completely gone */
  327.  
  328.   if (p[0] == 'I' && !vowel (p[-1]))
  329.     {
  330.       p[0] = 'Y';
  331.       if (cflag)
  332.     flagpr (w, 'D', p);
  333.       else if ((dent = lookup (w, n, 1)) != NULL
  334.            && dent->d_flag)
  335.     {
  336.       wordok = 1;
  337.       return;
  338.     }
  339.       p[0] = 'I';
  340.     }
  341.  
  342.   if ((p[0] != 'E' && p[0] != 'Y') ||
  343.       (p[0] == 'Y' && vowel (p[-1])))
  344.     {
  345.       if (cflag)
  346.     flagpr (w, 'D', p + 1);
  347.       else if ((dent = lookup (w, n, 1)) != NULL)
  348.     {
  349.       if (dent->d_flag)
  350.         wordok = 1;
  351.       return;
  352.     }
  353.     }
  354. }
  355.  
  356. void 
  357. t_ending (char *w, int n)
  358. {
  359.  
  360.   register char *p;
  361.   register struct dent *dent;
  362.  
  363.   p = w + n - 3;
  364.  
  365.   if (strcmp (p, "EST") != 0)
  366.     return;
  367.  
  368.   p[1] = 0;            /* kill "ST" */
  369.   n -= 2;
  370.  
  371.   if (cflag)
  372.     flagpr (w, 'T', p);
  373.   else if ((dent = lookup (w, n, 1)) != NULL
  374.        && dent->t_flag)
  375.     {
  376.       wordok = 1;
  377.       return;
  378.     }
  379.  
  380.   if (n < 3)
  381.     return;
  382.  
  383.   p[0] = 0;            /* kill 'E' */
  384.   n--;
  385.   p--;
  386.  
  387.   /* EST is now completely gone */
  388.  
  389.   if (p[0] == 'I' && !vowel (p[-1]))
  390.     {
  391.       p[0] = 'Y';
  392.       if (cflag)
  393.     flagpr (w, 'T', p);
  394.       else if ((dent = lookup (w, n, 1)) != NULL
  395.            && dent->t_flag)
  396.     {
  397.       wordok = 1;
  398.       return;
  399.     }
  400.       p[0] = 'I';
  401.     }
  402.  
  403.   if ((p[0] != 'E' && p[0] != 'Y') ||
  404.       (p[0] == 'Y' && vowel (p[-1])))
  405.     {
  406.       if (cflag)
  407.     flagpr (w, 'T', p + 1);
  408.       else if ((dent = lookup (w, n, 1)) != NULL)
  409.     {
  410.       if (dent->t_flag)
  411.         wordok = 1;
  412.       return;
  413.     }
  414.     }
  415.  
  416. }
  417.  
  418.  
  419. void 
  420. r_ending (char *w, int n)
  421. {
  422.   register char *p;
  423.   register struct dent *dent;
  424.  
  425.   p = w + n - 2;
  426.  
  427.   if (strcmp (p, "ER") != 0)
  428.     return;
  429.  
  430.   p[1] = 0;            /* kill 'R' */
  431.   n--;
  432.  
  433.   if (cflag)
  434.     flagpr (w, 'R', p + 1);
  435.   else if ((dent = lookup (w, n, 1)) != NULL
  436.        && dent->r_flag)
  437.     {
  438.       wordok = 1;
  439.       return;
  440.     }
  441.  
  442.   if (n < 3)
  443.     return;
  444.  
  445.   p[0] = 0;            /* kill 'E' */
  446.   n--;
  447.   p--;
  448.  
  449.   /* ER is now completely gone */
  450.  
  451.   if (p[0] == 'I' && !vowel (p[-1]))
  452.     {
  453.       p[0] = 'Y';
  454.       if (cflag)
  455.     flagpr (w, 'R', p);
  456.       else if ((dent = lookup (w, n, 1)) != NULL
  457.            && dent->r_flag)
  458.     {
  459.       wordok = 1;
  460.       return;
  461.     }
  462.       p[0] = 'I';
  463.     }
  464.  
  465.   if ((p[0] != 'E' && p[0] != 'Y') ||
  466.       (p[0] == 'Y' && vowel (p[-1])))
  467.     {
  468.       if (cflag)
  469.     flagpr (w, 'R', p + 1);
  470.       else if ((dent = lookup (w, n, 1)) != NULL)
  471.     {
  472.       if (dent->r_flag)
  473.         wordok = 1;
  474.       return;
  475.     }
  476.     }
  477.  
  478. }
  479.  
  480. void 
  481. h_ending (char *w, int n)
  482. {
  483.   register char *p;
  484.   register struct dent *dent;
  485.  
  486.   p = w + n - 2;
  487.  
  488.   if (strcmp (p, "TH") != 0)
  489.     return;
  490.  
  491.   *p = 0;            /* kill "TH" */
  492.   n -= 2;
  493.  
  494.   p -= 2;
  495.  
  496.   if (p[1] != 'Y')
  497.     {
  498.       if (cflag)
  499.     flagpr (w, 'H', p + 2);
  500.       else if ((dent = lookup (w, n, 1)) != NULL
  501.            && dent->h_flag)
  502.     wordok = 1;
  503.     }
  504.  
  505.   if (strcmp (p, "IE") != 0)
  506.     return;
  507.  
  508.   p[0] = 'Y';            /* change "IE" to "Y" */
  509.   p[1] = 0;
  510.   n--;
  511.  
  512.   if (cflag)
  513.     flagpr (w, 'H', p + 1);
  514.   else if ((dent = lookup (w, n, 1)) != NULL)
  515.     if (dent->h_flag)
  516.       wordok = 1;
  517.  
  518. }
  519.  
  520. /*
  521.  * check for flags: X, J, Z, S, P, M
  522.  *
  523.  * X    -ions or -ications or -ens
  524.  * J    -ings
  525.  * Z    -ers or -iers
  526.  * S    -ies or -es or -s
  527.  * P    -iness or -ness
  528.  * M    -'S
  529.  */
  530.  
  531. void 
  532. s_ending (char *w, int n)
  533. {
  534.   register char *p;
  535.   register struct dent *dent;
  536.  
  537.   p = w + n;
  538.  
  539.   p[-1] = 0;            /* kill 'S' */
  540.   n--;
  541.  
  542.   if (strchr ("SXZHY", p[-2]) == NULL || (p[-2] == 'Y' && vowel (p[-3])))
  543.     {
  544.       if (cflag)
  545.     flagpr (w, 'S', p - 1);
  546.       else if ((dent = lookup (w, n, 1)) != NULL
  547.            && dent->s_flag)
  548.     {
  549.       wordok = 1;
  550.       return;
  551.     }
  552.     }
  553.  
  554.  
  555.   switch (p[-2])
  556.     {                /* letter before S */
  557.     case 'N':            /* X */
  558.       if (strcmp (p - 4, "ION") == 0)
  559.     {
  560.       p[-4] = 'E';        /* change "ION" to "E" */
  561.       p[-3] = 0;
  562.       n -= 2;
  563.       if (cflag)
  564.         flagpr (w, 'X', p - 4);
  565.       else if ((dent = lookup (w, n, 1)) != NULL
  566.            && dent->x_flag)
  567.         {
  568.           wordok = 1;
  569.           return;
  570.         }
  571.     }
  572.       if (strcmp (p - 8, "ICATE") == 0)
  573.     {
  574.       p[-8] = 'Y';        /* change "ICATE" to "Y" */
  575.       p[-7] = 0;
  576.       n -= 4;
  577.       if (cflag)
  578.         flagpr (w, 'X', p - 8);
  579.       else if ((dent = lookup (w, n, 1)) != NULL
  580.            && dent->x_flag)
  581.         wordok = 1;
  582.       return;
  583.     }
  584.       if (strcmp (p - 3, "EN") == 0 && p[-4] != 'E' && p[-4] != 'Y')
  585.     {
  586.       p[-3] = 0;        /* kill "EN" */
  587.       n -= 2;
  588.       if (cflag)
  589.         flagpr (w, 'X', p - 3);
  590.       else if ((dent = lookup (w, n, 1)) != NULL
  591.            && dent->x_flag)
  592.         wordok = 1;
  593.       return;
  594.     }
  595.       return;
  596.     case 'G':            /* J */
  597.       if (strcmp (p - 4, "ING") != 0)
  598.     return;
  599.       p[-4] = 'E';        /* change "ING" to "E" */
  600.       p[-3] = 0;
  601.       n -= 2;
  602.       if (cflag)
  603.     flagpr (w, 'J', p - 4);
  604.       else if ((dent = lookup (w, n, 1)) != NULL
  605.            && dent->j_flag)
  606.     {
  607.       wordok = 1;
  608.       return;
  609.     }
  610.       if (p[-5] == 'E')
  611.     return;            /* This stops CREATEING */
  612.       p[-4] = 0;        /* kill 'E' */
  613.       n--;
  614.       if (cflag)
  615.     flagpr (w, 'J', p - 4);
  616.       else if ((dent = lookup (w, n, 1)) != NULL
  617.            && dent->j_flag)
  618.     wordok = 1;
  619.       return;
  620.     case 'R':            /* Z */
  621.       if (strcmp (p - 3, "ER") != 0)
  622.     return;
  623.  
  624.       p[-2] = 0;        /* kill 'R' */
  625.       n--;
  626.       if (cflag)
  627.     flagpr (w, 'Z', p - 2);
  628.       else if ((dent = lookup (w, n, 1)) != NULL
  629.            && dent->z_flag)
  630.     {
  631.       wordok = 1;
  632.       return;
  633.     }
  634.       if (p[-4] == 'I' && !vowel (p[-5]))
  635.     {
  636.       p[-4] = 'Y';        /* change "IE" to "Y" */
  637.       p[-3] = 0;
  638.       n--;
  639.       if (cflag)
  640.         flagpr (w, 'Z', p - 4);
  641.       else if ((dent = lookup (w, n, 1)) != NULL
  642.            && dent->z_flag)
  643.         {
  644.           wordok = 1;
  645.           return;
  646.         }
  647.       p[-4] = 'I';        /* change 'Y' to 'I' */
  648.     }
  649.       if ((p[-4] != 'E' && p[-4] != 'Y') ||
  650.       (p[-4] == 'Y' && vowel (p[-5])))
  651.     {
  652.       if (p[-3])
  653.         n--;
  654.       p[-3] = 0;
  655.       if (cflag)
  656.         flagpr (w, 'Z', p - 3);
  657.       else if ((dent = lookup (w, n, 1)) != NULL
  658.            && dent->z_flag)
  659.         wordok = 1;
  660.     }
  661.       return;
  662.     case 'E':            /* S (except simple adding of an S) */
  663.       p[-2] = 0;        /* drop the E */
  664.       n--;
  665.       if (strchr ("SXZH", p[-3]) != NULL)
  666.     {
  667.       if (cflag)
  668.         flagpr (w, 'S', p - 2);
  669.       else if ((dent = lookup (w, n, 1)) != NULL)
  670.         {
  671.           if (dent->s_flag)
  672.         wordok = 1;;
  673.           return;
  674.         }
  675.     }
  676.       if (p[-3] == 'I' && !vowel (p[-4]))
  677.     {
  678.       p[-3] = 'Y';
  679.       if (cflag)
  680.         flagpr (w, 'S', p - 3);
  681.       else if ((dent = lookup (w, n, 1)) != NULL
  682.            && dent->s_flag)
  683.         wordok = 1;
  684.       return;
  685.     }
  686.       return;
  687.  
  688.     case 'S':            /* P */
  689.       if (strcmp (p - 4, "NES") != 0)
  690.     return;
  691.  
  692.       p[-4] = 0;        /* kill "NES" */
  693.       n -= 3;
  694.       if (p[-5] != 'Y' || vowel (p[-6]))
  695.     {
  696.       if (cflag)
  697.         flagpr (w, 'P', p - 4);
  698.       else if ((dent = lookup (w, n, 1)) != NULL
  699.            && dent->p_flag)
  700.         {
  701.           wordok = 1;
  702.           return;
  703.         }
  704.     }
  705.       if (p[-5] == 'I')
  706.     {
  707.       p[-5] = 'Y';
  708.       if (cflag)
  709.         flagpr (w, 'P', p - 5);
  710.       else if ((dent = lookup (w, n, 1)) != NULL
  711.            && dent->p_flag)
  712.         wordok = 1;
  713.     }
  714.       return;
  715.     case '\'':            /* M */
  716.       p[-2] = '\0';        /* kill "'" */
  717.       n--;
  718.       if (cflag)
  719.     flagpr (w, 'M', p - 2);
  720.       else if ((dent = lookup (w, n, 1)) != NULL
  721.            && dent->m_flag)
  722.     wordok = 1;
  723.       return;
  724.     }
  725. }
  726.  
  727. /* only the N flag */
  728. void 
  729. n_ending (char *w, int n)
  730. {
  731.   register char *p;
  732.   register struct dent *dent;
  733.  
  734.   p = w + n;
  735.  
  736.   if (p[-2] == 'E')
  737.     {
  738.       if (p[-3] == 'E' || p[-3] == 'Y')
  739.     return;
  740.       p[-2] = 0;        /* kill "EN" */
  741.       n -= 2;
  742.       if (cflag)
  743.     flagpr (w, 'N', p - 2);
  744.       else if ((dent = lookup (w, n, 1)) != NULL
  745.            && dent->n_flag)
  746.     wordok = 1;
  747.       return;
  748.     }
  749.  
  750.   if (strcmp (p - 3, "ION") != 0)
  751.     return;
  752.  
  753.   p[-3] = 'E';            /* change "ION" to "E" */
  754.   p[-2] = 0;
  755.   n -= 2;
  756.  
  757.   if (cflag)
  758.     flagpr (w, 'N', p - 3);
  759.   else if ((dent = lookup (w, n, 1)) != NULL)
  760.     {
  761.       if (dent->n_flag)
  762.     wordok = 1;
  763.       return;
  764.     }
  765.  
  766.   if (strcmp (p - 7, "ICATE") != 0)    /* check is really against "ICATION" */
  767.     return;
  768.  
  769.   p[-7] = 'Y';            /* change "ICATE" to "Y" */
  770.   p[-6] = 0;
  771.   n -= 4;
  772.  
  773.   if (cflag)
  774.     flagpr (w, 'N', p - 7);
  775.   else if ((dent = lookup (w, n, 1)) != NULL && dent->n_flag)
  776.     wordok = 1;
  777.   return;
  778. }
  779.  
  780. /* flags: v */
  781. void 
  782. e_ending (char *w, int n)
  783. {
  784.   register char *p;
  785.   register struct dent *dent;
  786.  
  787.   p = w + n;
  788.  
  789.   if (strcmp (p - 3, "IVE") != 0)
  790.     return;
  791.   p[-3] = 'E';            /* change "IVE" to "E" */
  792.   p[-2] = 0;
  793.   n -= 2;
  794.  
  795.   if (cflag)
  796.     flagpr (w, 'V', p - 3);
  797.   else if ((dent = lookup (w, n, 1)) != NULL
  798.        && dent->v_flag)
  799.     {
  800.       wordok = 1;
  801.       return;
  802.     }
  803.  
  804.   if (p[-4] == 'E')
  805.     return;
  806.  
  807.   p[-3] = 0;            /* kill 'E' */
  808.   n--;
  809.  
  810.   if (cflag)
  811.     flagpr (w, 'V', p - 3);
  812.   else if ((dent = lookup (w, n, 1)) != NULL && dent->v_flag)
  813.     wordok = 1;
  814.   return;
  815. }
  816.  
  817. /* flags: y */
  818. void 
  819. y_ending (char *w, int n)
  820. {
  821.   register char *p;
  822.   register struct dent *dent;
  823.  
  824.   p = w + n;
  825.  
  826.   if (strcmp (p - 2, "LY") != 0)
  827.     return;
  828.  
  829.   p[-2] = 0;            /* kill "LY" */
  830.   n -= 2;
  831.  
  832.   if (cflag)
  833.     flagpr (w, 'Y', p - 2);
  834.   else if ((dent = lookup (w, n, 1)) != NULL && dent->y_flag)
  835.     wordok = 1;
  836.   return;
  837. }
  838.  
  839. int 
  840. vowel (int c)
  841. {
  842.   return (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U');
  843. }
  844.